//-------------------------------------------------------------------------------------------------------
//      Copyright (c) 2005-2007, Be Nanashi-San 
// 
//      Permission is hereby granted, free of charge, to any person obtaining a 
//      copy of this software and associated documentation files (the "Software"), 
//      to deal in the Software without restriction, including without limitation 
//      the rights to use, copy, modify, merge, publish, distribute, sublicense, 
//      and/or sell copies of the Software, and to permit persons to whom the 
//      Software is furnished to do so, subject to the following conditions: 
// 
//      The above copyright notice and this permission notice shall be included in 
//      all copies or substantial portions of the Software. 
// 
//      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
//      IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
//      FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
//      AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
//      LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
//      FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
//      DEALINGS IN THE SOFTWARE. 
// 
//      File Name:   	MonaList.cpp
//      Author:      	Be Nanashi-San@598 in "BeOS - Zeta R4" Thread 
//						(http://pc8.2ch.net/test/read.cgi/os/1120676818/598)
//		Description:	datファイルをBListのようにアクセスし、
//						各項目(<>を区切りとして)をargcとargv[]で受け取る
//-------------------------------------------------------------------------------------------------------
#include <File.h>
#include <stdio.h>	// SEEK_SET etc.
#include <string.h>	// strncpy
#include "MonaList.h"
#include "Util.h"		// cutf8

////////////////////////////////////////////////////////////////////////////////
// MonaList
//
//
////////////////////////////////////////////////////////////////////////////////
MonaList::MonaList()
{
}
////////////////////////////////////////////////////////////////////////////////
// InitCheck
//
//
////////////////////////////////////////////////////////////////////////////////
status_t
MonaList::InitCheck()
{
	fOffsets.clear();
	fOffsets.reserve(1024);
	fBuf.SetSize(0);
	fBuf.Seek(0, SEEK_SET);
	return B_OK;
}
////////////////////////////////////////////////////////////////////////////////
// SetTo
//
//
////////////////////////////////////////////////////////////////////////////////
status_t
MonaList::SetTo(BPositionIO *file)
{
	file->Seek(0, SEEK_SET);
	fBuf.Seek(0, SEEK_SET);
	::cutf8(file, &fBuf);

	uint32 offset = 0;
	const char *data = static_cast<const char*>(fBuf.Buffer());
	for (uint32 s = 0; s < fBuf.BufferLength(); s++, data++) {
		if (*data == '\n') {
			fOffsets.push_back(offset);
			offset = s + 1;
		}
	}

	return B_OK;
}
////////////////////////////////////////////////////////////////////////////////
// OffsetAt
//
// 20060507:修正
////////////////////////////////////////////////////////////////////////////////
void
MonaList::OffsetAt(int32 var, int32 *argc, const char *argv[])
{
	//20051123:AAすれ用に増量。
	/* メモリーリーク脆弱性   レスはdist内に展開される。
	そのため4000程度以下でなければ正しく動作しない。 オーバーランをチェックしていないが、
	2ch自体、長いレスは書きコできない問題ないと思うのだが。 */
	#define DIST_SIZ (4096 * 4)
	static char dist[DIST_SIZ];	
	const char *data = static_cast<const char*>(fBuf.Buffer()) + fOffsets[var];
	*argc = 0;
	char *d = dist;
	char *offset = d;
	
	while (data[0] != '\n' && d < dist + DIST_SIZ) {
		//20060509:<b>および</b>は区切り文字"<>"検出前に削除して置く
		if (data[0] == '<'){
			if(data[1] == 'b' && data[2] == '>') {
				data += 3;
			}else if (data[1] == '/' && data[2] == 'b' && data[3] == '>') {
				data += 4;
			}else if (data[1] == 'h' && data[2] == 'r' && data[3] == '>') {
				data += 4;
			}else if (strncmp(data, "</font>"  , 7) == 0) {
				data += 7;
			}else if(strncmp(data, "<font"  , 5) == 0) {
				while (*data++ != '>' ) ;
			}
		}	

		if (data[0] == '<' && data[1] == '>') {
			if (*argc < 4) argv[(*argc)++] = offset;
			*d++ = '\0';
			offset = d;
			data += 2;
			continue;
		}
		
		if (data[0] == 'h' || data[0] == 't') {
			bool http = false;
			for (int32 i = 0; i < 2; i++) {
				if (strncmp(data, "http://" + i, 7 - i) == 0) {
					strcpy(d, "http://");
					data += 7 - i;
					d += 7;
					http = true;
				}
			}
			if (! http) *d++ = *data++;
		}else{
			*d++ = *data++;
		}
	}

	*d = '\0';
	argv[(*argc)++] = offset;
	argv[(*argc)] = NULL;
}
